package io.github.wslxm.springbootplus2.core.utils.date;

import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 时间处理工具类
 *
 * @author ws
 * @mail 1720696548@qq.com
 * @date 2020/4/24 0024 9:54
 * @return
 */
@Slf4j
public class XjLocalDateTimeUtil {


    /**
     * 获取时间类型
     * 1-包含开始和结束时间(默认)
     * 2-包含结束-不包含开始时间   // 开始时间+1天
     * 3-包含开始-不包含结束时间   // 结束时间-1天
     * 4-不包含开始和结束时间 // 开始时间+1天  or 结束时间-1天
     */
    private static final int BETWEEN_TYPE_ONE = 1;
    private static final int BETWEEN_TYPE_TWO = 2;
    private static final int BETWEEN_TYPE_THREE = 3;
    private static final int BETWEEN_TYPE_FOUR = 4;

    private static Random random;

    static {
        try {
            random = SecureRandom.getInstanceStrong();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断时间 小于
     * <P>   t1 < t2 = true （如：2019-10-13 11:11:00 < 2020-11-13 13:13:00 = true）  </P>
     *
     * @author wangsong
     */
    public static boolean isBefore(LocalDateTime t1, LocalDateTime t2) {
        return t1.isBefore(t2);
    }

    /**
     * 判断时间 大于
     * <P>   t1 > t2 = true  </P>
     *
     * @author wangsong
     */
    public static boolean isAfter(LocalDateTime t1, LocalDateTime t2) {
        return t1.isAfter(t2);
    }


    /**
     * 自构建 LocalDateTime ==> 年，月，日，时，分
     *
     * @author wangsong
     */
    public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute) {
        return LocalDateTime.of(year, month, dayOfMonth, hour, minute);
    }

    /**
     * 自构建 LocalDateTime ==> 年，月，日，时，分，秒，毫秒（精确到9位数）
     *
     * @author wangsong
     */
    public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) {
        return LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
    }


    //========================================================================================================
    //========================================================================================================
    //========================================================================================================
    //============================================== 时间获取 =================================================
    //========================================================================================================
    //========================================================================================================

    /**
     * 获取指定某一天的开始时间 00:00:00
     *
     * @param time
     * @return java.time.LocalDateTime
     * @author wangsong
     * @date 2020/12/24 0024 15:10
     * @version 1.0.1
     */
    public static LocalDateTime getDayStart(LocalDateTime time) {
        return time.withHour(0)
                .withMinute(0)
                .withSecond(0)
                .withNano(0);
    }


    /**
     * 获取指定某一天的结束时间  23:59:59.999999
     *
     * @author wangsong
     */
    public static LocalDateTime getDayEnd(LocalDateTime time) {
        // 年 月  天 时 分 秒 毫秒（这里精确到6位数）
        return time.withHour(23)
                .withMinute(59)
                .withSecond(59)
                .withNano(999999);
    }

    /**
     * 获取指定时间是周几  1到7
     *
     * @author wangsong
     */
    public static int week(LocalDateTime time) {
        return time.getDayOfWeek().getValue();
    }


    /**
     * 获取指定时间之后的日期
     * <P>  根据field不同加不同值 , field为ChronoUnit.*
     * 秒   ChronoUnit.SECONDS
     * 分   ChronoUnit.MINUTES
     * 时   ChronoUnit.HOURS
     * 半天  ChronoUnit.HALF_DAYS
     * 天    ChronoUnit.DAYS
     * 月    ChronoUnit.MONTHS
     * 年    ChronoUnit.YEARS
     * </P>
     *
     * @author wangsong
     */
    public static LocalDateTime plus(LocalDateTime time, long number, TemporalUnit field) {
        return time.plus(number, field);
    }

    public static String plus(String timeStr, long number, TemporalUnit field) {
        LocalDateTime time = XjLocalDateTimeUtil.plus(XjLocalDateTimeUtil.parse(timeStr), number, field);
        return XjLocalDateTimeUtil.parse(time);
    }


    /**
     * 获取指定时间之前的日期
     *
     * @author wangsong
     * <P> 根据field不同减不同值, field 为 ChronoUnit.*
     * 秒   ChronoUnit.SECONDS
     * 分   ChronoUnit.MINUTES
     * 时   ChronoUnit.HOURS
     * 半天  ChronoUnit.HALF_DAYS
     * 天    ChronoUnit.DAYS
     * 月    ChronoUnit.MONTHS
     * 年    ChronoUnit.YEARS
     * </P>
     * @version 1.0.1
     */
    public static LocalDateTime subtract(LocalDateTime time, long number, TemporalUnit field) {
        return time.minus(number, field);
    }


    public static String subtract(String timeStr, long number, TemporalUnit field) {
        LocalDateTime time = XjLocalDateTimeUtil.subtract(XjLocalDateTimeUtil.parse(timeStr), number, field);
        return XjLocalDateTimeUtil.parse(time);
    }

    /**
     * 获取两个日期的时间差
     *
     * @param startTime 开始时间
     * @param endTime   计算时间
     * @param field     根据field不同减不同值 , field 为 ChronoUnit.*
     * @return startTime小 endTime大 返回正数，则反之
     * @author wangsong
     * <p>
     * 秒    ChronoUnit.SECONDS
     * 分    ChronoUnit.MINUTES
     * 时    ChronoUnit.HOURS
     * 半天  ChronoUnit.HALF_DAYS
     * 天    ChronoUnit.DAYS
     * 月    ChronoUnit.MONTHS
     * 年    ChronoUnit.YEARS
     * </P>
     */
    public static long betweenTwoTime(LocalDateTime startTime, LocalDateTime endTime, ChronoUnit field) {
        Period period = Period.between(LocalDate.from(startTime), LocalDate.from(endTime));
        if (field == ChronoUnit.YEARS) {
            return period.getYears();
        }
        if (field == ChronoUnit.MONTHS) {
            return period.getYears() * 12L + period.getMonths();
        }
        return field.between(startTime, endTime);
    }


    /**
     * 获取指定时间 加或减N周的第一天 00:00:00
     *
     * @author wangsong
     */
    public static LocalDateTime weekFirstDay(LocalDateTime time, int num) {
        int week = week(LocalDateTime.now());
        LocalDateTime newTime = subtract(LocalDateTime.now(), week - 1L, ChronoUnit.DAYS);
        newTime = plus(newTime, num * 7L, ChronoUnit.DAYS);
        return getDayStart(newTime);
    }


    /**
     * 获取指定时间 加或减N周的最后一天  23:59:59:999999
     *
     * @author wangsong
     */
    public static LocalDateTime weekLastDay(LocalDateTime time, int num) {
        int week = week(LocalDateTime.now());
        LocalDateTime newTime = plus(LocalDateTime.now(), 7L - week, ChronoUnit.DAYS);
        newTime = plus(newTime, num * 7L, ChronoUnit.DAYS);
        return getDayEnd(newTime);
    }


    /**
     * 获取指定月 加或减N月的第一天 00:00:00
     *
     * @author wangsong
     */
    public static LocalDateTime monthFirstDay(LocalDateTime time, int num) {
        LocalDateTime newTime = plus(time, num, ChronoUnit.MONTHS);
        newTime = newTime.with(TemporalAdjusters.firstDayOfMonth());
        return getDayStart(newTime);
    }

    /**
     * 获取指定月 加或减N月的最后一天 23:59:59:999999
     *
     * @author wangsong
     */
    public static LocalDateTime monthLastDay(LocalDateTime time, int num) {
        LocalDateTime newTime = plus(time, num, ChronoUnit.MONTHS);
        newTime = newTime.with(TemporalAdjusters.lastDayOfMonth());
        return getDayEnd(newTime);
    }


    /**
     * 获取指定年 加或减N年的第一天 00:00:00
     *
     * @author wangsong
     */
    public static LocalDateTime yearFirstDay(LocalDateTime time, int num) {
        LocalDateTime newTime = plus(time, num, ChronoUnit.YEARS);
        int year = newTime.getYear();
        // 年 月  天 时 分 秒 毫秒（这里精确到9位数）
        return LocalDateTime.of(year, 1, 1, 0, 0, 0);
    }

    /**
     * 获取指定年 加或减N年最后一天  23:59:59:999999
     *
     * @author wangsong
     */
    public static LocalDateTime yearLastDay(LocalDateTime time, int num) {
        LocalDateTime newTime = subtract(time, num, ChronoUnit.YEARS);
        int year = newTime.getYear();
        // 年 月  天 时 分 秒 毫秒（这里精确到6位数）
        return LocalDateTime.of(year, 12, 31, 23, 59, 59, 999999);
    }


    /**
     * 获取17位时间戳字符串+3位随机数
     * <p>  这里增加了延时一毫秒，单体项目100%不会重复，可用于生成订单号  </p>
     * 20200101125959999  2020-01-01 12:59:59:999
     *
     * @return
     * @author wangsong
     */
    public static String getNo() {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String timeStamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        timeStamp += (random.nextInt(10) + "") + (random.nextInt(10) + "") + (random.nextInt(10) + "");
        return timeStamp;
    }


    /**
     * 获取整点--  把指定时间的 分+秒设置为0
     * <P>
     * 把指定时间的 分+秒设置为0 (舍弃分秒模式)
     * yyyy-MM-dd HH:00:00
     * </P>
     *
     * @param time time
     * @return java.time.LocalDateTime
     * @author wangsong
     * @date 2020/12/24 0024 15:10
     * @version 1.0.1
     */
    public  static LocalDateTime getTheHour(LocalDateTime time) {

        // 分   // 秒   // 毫秒（这里精确到9位数）
        return time.withMinute(0)
                .withSecond(0)
                .withNano(0);
    }


    /**
     * 获取整分--  把指定时间的 秒设置为0
     * <P>
     *     把指定时间的 秒设置为0 (舍弃秒模式)
     *     yyyy-MM-dd HH:mm:00
     * </P>
     * @param time
     * @return java.time.LocalDateTime
     * @author wangsong
     * @date 2020/12/24 0024 15:21
     * @version 1.0.1
     */
    public static LocalDateTime getTheMinute(LocalDateTime time) {
        // 秒    // 毫秒（这里精确到9位数）
        return time.withSecond(0).withNano(0);
    }


    //========================================================================================================
    //========================================================================================================
    //========================================================================================================
    //============================================== 转换相关 =================================================
    //========================================================================================================
    //========================================================================================================

    /**
     * LocalDateTime 转为 天 的字符串，如 1号返回 01
     *
     * @author wangsong
     */
    public static Integer parseDayInt(LocalDateTime time) {
        return Integer.parseInt(parse(time, "dd"));
    }


    /**
     * Date 转 LocalDateTime
     *
     * @author wangsong
     */
    public static LocalDateTime parseLdt(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * LocalDateTime 转 Date
     *
     * @author wangsong
     */
    public static Date parseDate(LocalDateTime time) {
        return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDateTime 转 毫秒
     *
     * @author wangsong
     */
//    public static Long parseMillisecond(LocalDateTime time) {
//        return time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
//    }
//
//    /**
//     * LocalDateTime 转 秒
//     *
//     * @author wangsong
//     */
//    public static Long parseSecond(LocalDateTime time) {
//        return time.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
//    }


    /**
     * 将 时间戳 转 LocalDateTime (秒级)
     *
     * @return java.lang.String
     * @author wangsong
     * @date 2021/5/12 0012 17:13
     * @version 1.0.1
     */
    public static LocalDateTime parseTimestamp(Long timestamp) {
        return LocalDateTime.ofEpochSecond(timestamp, 0, ZoneOffset.ofHours(8));
    }


    /**
     * 将LocalDateTime 转 为时间戳 (秒级)
     *
     * @return java.lang.String
     * @author wangsong
     * @date 2021/5/12 0012 17:13
     * @version 1.0.1
     */
    public static Long parseTimestamp(LocalDateTime time) {
        return time.toEpochSecond(ZoneOffset.ofHours(8));
    }


    /**
     * 将时间戳转 为 LocalDateTime  (毫秒级)
     *
     * @param timestamp
     * @return java.lang.String
     * @author wangsong
     * @date 2021/5/12 0012 17:13
     * @version 1.0.1
     */
    public static LocalDateTime parseTimestampMilli(Long timestamp) {
        return LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8));
    }


    /**
     *  将LocalDateTime 转 为时间戳 (毫秒级)
     *
     * @param time 时间
     * @return {@link Long}
     */
    public static Long parseTimestampMilli(LocalDateTime time) {
        return time.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
    }

    /**
     * String 类型转成 LocalDateTime ,必须为完整时间,如：2020-01-20 00:00:00
     *
     * @param timeStr 时间字符串
     * @return java.time.LocalDateTime
     */
    public static LocalDateTime parse(String timeStr) {
        return parse(timeStr, DateFormat.YYYY_MM_DD_HH_MM_SS);
    }


    /**
     * String (2020-01-20 00:00:00)类型转成 LocalDateTime
     *
     * @param timeStr timeStr 时间字符串
     * @param pattern pattern 格式
     * @return java.time.LocalDateTime
     */
    public static LocalDateTime parse(String timeStr, String pattern) {
        if (pattern.equals(DateFormat.YYYY)) {
            timeStr += "-01-01 00:00:00";
        } else if (pattern.equals(DateFormat.YYYY_MM)) {
            timeStr += "-01 00:00:00";
        } else if (pattern.equals(DateFormat.YYYY_MM_DD)) {
            timeStr += " 00:00:00";
        } else if (pattern.equals(DateFormat.YYYY_MM_DD_HH)) {
            timeStr += ":00:00";
        } else if (pattern.equals(DateFormat.YYYY_MM_DD_HH_MM)) {
            timeStr += ":00";
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DateFormat.YYYY_MM_DD_HH_MM_SS);
        return LocalDateTime.parse(timeStr, dtf);
    }


    /**
     * LocalDateTime 转完整 String 类型的时间 如：2020-01-20 00:00:00
     *
     * @param time time
     * @return java.lang.String
     */
    public static String parse(LocalDateTime time) {
        return parse(time, DateFormat.YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * LocalDateTime 转指定类型的字符串
     *
     * @param time    time    时间
     * @param pattern pattern 格式
     * @return java.lang.String
     * @author wangsong
     */
    public static String parse(LocalDateTime time, String pattern) {
        if (time == null) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);
        return df.format(time);
    }


    /**
     * Date 转指定格式的字符串
     *
     * @param time
     * @author wangsong
     */
    public static String parse(Date time, String pattern) {
        if (time == null) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(time);
    }

    /**
     * 判断一个时间是否是今天
     *
     * @param time 时间
     * @return  true-是 fasle-否
     */
    public static boolean isItToday(LocalDateTime time) {
        LocalDate currentDate = LocalDate.now();
        LocalDate givenDate = LocalDate.of(time.getYear(), time.getMonth(), time.getDayOfMonth());
        return givenDate.isEqual(currentDate);
    }

    /**
     * 判断一个时间是否是今天
     *
     * @param timeStr 时间 字符串
     * @return  true-是 fasle-否
     */
    public static boolean isItToday(String timeStr) {
        LocalDateTime time = parse(timeStr);
        LocalDate currentDate = LocalDate.now();
        LocalDate givenDate = LocalDate.of(time.getYear(), time.getMonth(), time.getDayOfMonth());
        return givenDate.isEqual(currentDate);
    }


    /**
     * 获取指定天的24小时(0-23)  |  yyyy-MM-dd HH 格式
     *
     * @param t 开始月
     * @return
     */
    public static List<String> getDay24Hour(LocalDateTime t) {
        if (t == null) {
            return new ArrayList<>();
        }
        List<String> times = new ArrayList<>();
        String time = parse(t, DateFormat.YYYY_MM_DD);
        int hourNum = 24;
        for (int i = 0; i < hourNum; i++) {
            if (i < 10) {
                times.add(time + " 0" + i);
            } else {
                times.add(time + " " + i);
            }
        }
        return times;
    }


    /**
     * 获取每一天的时间 (指定时间 前n月前的第一天 到 n月后的最后一天的所有时间)
     * <P>  一天一条数据 List<DateDays>  </P>
     *
     * @param startNum 前n月，当前月开始为 0
     * @param endNum   后n月，当前月就是为 0
     * @return java.util.List<com.lplb.common.utils.LocalDateTimeUtil.DateDays>
     * @author wangsong
     */
    public static List<DateDays> getBetweenDaysUpListByMonth(LocalDateTime time, Integer startNum, Integer endNum) {
        // 本月第一天  00:00:00
        LocalDateTime startTime = monthFirstDay(time, startNum);
        // n月后的最后一天 23:59:59.999
        LocalDateTime endTime = monthLastDay(time, endNum);
        return getBetweenDaysUpList(startTime, endTime, BETWEEN_TYPE_ONE);
    }


    /**
     * 获取每一天的时间 (指定开始时间和结束时间)
     * <p>
     * 一天一条数据 List<DateDays>
     * 返回数据包括 开始时间 和 结束时间 的当天数据
     * </P>
     *
     * @param startTime 开始时间 (时分秒已开始时间位为准)
     * @param endTime   结束时间
     * @param type      1-包含开始和结束时间  2-包含结束-不包含开始时间  3-包含开始-不包含结束时间  4-不包含开始和结束时间
     * @return java.util.List<com.lplb.common.utils.LocalDateTimeUtil.DateDays>
     * @author wangsong
     */
    public static List<DateDays> getBetweenDaysUpList(LocalDateTime startTime, LocalDateTime endTime, Integer type) {
        List<DateDays> dateDaysList = new ArrayList<>();
        List<LocalDateTime> betweenList = getBetweenDaysList(startTime, endTime, type);
        for (LocalDateTime localDateTime : betweenList) {
            dateDaysList.add(new DateDays(localDateTime, week(localDateTime)));
        }
        return dateDaysList;
    }


    /**
     * 获取指定开始时间到指定结束时间的每一天, 包括开始时间，不包括结束时间，如：2020-5-16到2020-5-18 获得时间为：[2020-5-16,2020-5-17]
     *
     * @param startTime
     * @param endTime
     * @param type      1-包含开始和结束时间  2-包含结束-不包含开始时间  3-包含开始-不包含结束时间  4-不包含开始和结束时间
     * @return java.util.List<java.time.LocalDateTime>
     * @author wangsong
     * @date 2020/12/24 0024 15:16
     * @version 1.0.1
     */
    public static List<LocalDateTime> getBetweenDaysList(LocalDateTime startTime, LocalDateTime endTime, Integer type) {
        // 指定开始时间  00:00:00  // 指定结束时间  00:00:00
        LocalDateTime oldStartTime = getDayStart(startTime);
        LocalDateTime oldEndTime = getDayStart(endTime);
        // 1-包含开始和结束时间(默认) BetweenType
        // 2-包含结束-不包含开始时间   // 开始时间+1天
        // 3-包含开始-不包含结束时间   // 结束时间-1天
        // 4-不包含开始和结束时间 // 开始时间+1天  or 结束时间-1天
        if (type == BETWEEN_TYPE_TWO) {
            oldStartTime = plus(oldStartTime, 1, ChronoUnit.DAYS);
        } else if (type == BETWEEN_TYPE_THREE) {
            oldEndTime = subtract(endTime, 1, ChronoUnit.DAYS);
        } else if (type == BETWEEN_TYPE_FOUR) {
            oldStartTime = plus(oldStartTime, 1, ChronoUnit.DAYS);
            oldEndTime = subtract(endTime, 1, ChronoUnit.DAYS);
        }
        // 返回数据
        List<LocalDateTime> everyDays = new ArrayList<>();
        // 第一天数据
        everyDays.add(oldStartTime);
        while (true) {
            // 获取之后的每一天时间
            LocalDateTime nextDay = plus(everyDays.get(everyDays.size() - 1), 1, ChronoUnit.DAYS);
            // 大于最后一天-跳出循环
            if (isAfter(nextDay, oldEndTime)) {
                break;
            }
            everyDays.add(nextDay);
        }
        return everyDays;
    }


    /**
     * 获取月 (返回每一个月的字串， yyyy-MM 格式)
     * <p> 包含结束月，不包含开始月 </>
     *
     * @param startTime 开始月
     * @param endTime   结束月
     * @return
     */
    public static List<String> getBetweenMonthsList(LocalDateTime startTime, LocalDateTime endTime) {
        List<String> times = new ArrayList<>();
        if (startTime != null && endTime != null) {
            // 获取开始月的第一天
            endTime = monthFirstDay(endTime, 0);
            times.add(parse(startTime, DateFormat.YYYY_MM));
            while (isBefore(startTime, endTime)) {
                startTime = plus(startTime, 1, ChronoUnit.MONTHS);
                times.add(parse(startTime, DateFormat.YYYY_MM));
            }
        }
        return times;
    }


    /**
     * 时间分频器
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param dayNum  分段天数 (每几天拆为一段)
     * @return {@link List}<{@link TimeDivider}> sectionalizer
     */
    public static List<TimeDivider> divider(String startTime, String endTime, int dayNum) {
        LocalDateTime oldStartTime = XjLocalDateTimeUtil.parse(startTime);
        long num = XjLocalDateTimeUtil.betweenTwoTime(oldStartTime, XjLocalDateTimeUtil.parse(endTime), ChronoUnit.DAYS);
        List<TimeDivider> times = new ArrayList<>();
        if (num > dayNum) {
            while (true) {
                LocalDateTime next = XjLocalDateTimeUtil.plus(oldStartTime, dayNum, ChronoUnit.DAYS);
                if (XjLocalDateTimeUtil.isAfter(next, XjLocalDateTimeUtil.parse(endTime))) {
                    // 最后一次，判断开始时间和结束时间是否相等
                    if (!XjLocalDateTimeUtil.parse(oldStartTime).equals(endTime)) {
                        TimeDivider time = new TimeDivider(XjLocalDateTimeUtil.parse(oldStartTime), endTime);
                        times.add(time);
                    }
                    break;
                } else {
                    TimeDivider time = new TimeDivider(XjLocalDateTimeUtil.parse(oldStartTime), XjLocalDateTimeUtil.parse(next));
                    times.add(time);
                    oldStartTime = XjLocalDateTimeUtil.plus(oldStartTime, dayNum, ChronoUnit.DAYS);
                }
            }
        } else {
            TimeDivider time = new TimeDivider(startTime, endTime);
            times = CollUtil.newArrayList(time);
        }
        return times;
    }

    /**
     * 测试方法
     *
     * @param args
     * @return void
     * @author ws
     * @mail 1720696548@qq.com
     * @date 2020/4/24 0024 15:54
     */
    public static void main(String[] args) {

        // log.info(subtract(LocalDateTime.now(), 1, ChronoUnit.YEARS).toString());
        //  log.info(getBetweenMonthsList(subtract(LocalDateTime.now(), 1, ChronoUnit.YEARS), LocalDateTime.now()).toString());
        //test();
        // test1();
        // test2();
        test3();
        // test4();
    }

    private static void test() {
        log.info("当前时间 ==> " + LocalDateTime.now());
        log.info("当前时间秒数 ==> " + parseTimestamp(LocalDateTime.now()));
        log.info("当前时间毫秒数 ==> " + parseTimestampMilli(LocalDateTime.now()));
        log.info("今天是几号：" + parseDayInt(LocalDateTime.now()));
        log.info("===========================================================");
        log.info("今天开始时间 ==> " + getDayStart(LocalDateTime.now()));
        log.info("今天结束时间 ==> " + getDayEnd(LocalDateTime.now()));
        log.info("构建自定义时间 ==> " + of(2020, 1, 1, 12, 00, 00, 999999999));
        log.info("指定格式 ==>  " + parse(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss:SSS"));
    }

    private static void test1() {
        log.info("=========================" + LocalDateTime.now() + " 之前 ==================================");
        log.info("10秒前 ==> " + subtract(LocalDateTime.now(), 10, ChronoUnit.SECONDS));
        log.info("10分前 ==> " + subtract(LocalDateTime.now(), 10, ChronoUnit.MINUTES));
        log.info("一小时前 ==> " + subtract(LocalDateTime.now(), 1, ChronoUnit.HOURS));
        log.info("半天前 ==> " + subtract(LocalDateTime.now(), 1, ChronoUnit.HALF_DAYS));
        log.info("一天前 ==> " + subtract(LocalDateTime.now(), 1, ChronoUnit.DAYS));
        log.info("一月前 ==> " + subtract(LocalDateTime.now(), 1, ChronoUnit.MONTHS));
        log.info("一年前 ==> " + subtract(LocalDateTime.now(), 1, ChronoUnit.YEARS));
        log.info("字符串支持 ==> " + subtract("2021-01-01 00:00:00", 1, ChronoUnit.YEARS));
        log.info("==========================" + LocalDateTime.now() + " 之后 ===================================");
        log.info("10秒后 ==> " + plus(LocalDateTime.now(), 10, ChronoUnit.SECONDS));
        log.info("10分后 ==> " + plus(LocalDateTime.now(), 10, ChronoUnit.MINUTES));
        log.info("一小时后 ==> " + plus(LocalDateTime.now(), 1, ChronoUnit.HOURS));
        log.info("半天后 ==> " + plus(LocalDateTime.now(), 1, ChronoUnit.HALF_DAYS));
        log.info("一天后 ==> " + plus(LocalDateTime.now(), 1, ChronoUnit.DAYS));
        log.info("一月后 ==> " + plus(LocalDateTime.now(), 1, ChronoUnit.MONTHS));
        log.info("一年后 ==> " + plus(LocalDateTime.now(), 1, ChronoUnit.YEARS));
        log.info("字符串支持 ==> " + plus("2021-01-01 00:00:00", 1, ChronoUnit.YEARS));
        log.info("================================= 时间差 =====================================");
        //  输出 ====>
        LocalDateTime start = LocalDateTime.of(2019, 10, 13, 11, 11);
        LocalDateTime end = LocalDateTime.of(2020, 11, 13, 13, 13);
        log.info("输出:" + parse(start, "yyyy-MM-dd HH:mm:ss") + " -到- " + parse(end, "yyyy-MM-dd HH:mm:ss") + "的时间差");
        log.info("年:" + betweenTwoTime(start, end, ChronoUnit.YEARS));
        log.info("月:" + betweenTwoTime(start, end, ChronoUnit.MONTHS));
        log.info("日:" + betweenTwoTime(start, end, ChronoUnit.DAYS));
        log.info("半日:" + betweenTwoTime(start, end, ChronoUnit.HALF_DAYS));
        log.info("小时:" + betweenTwoTime(start, end, ChronoUnit.HOURS));
        log.info("分钟:" + betweenTwoTime(start, end, ChronoUnit.MINUTES));
        log.info("秒:" + betweenTwoTime(start, end, ChronoUnit.SECONDS));
        log.info("毫秒:" + betweenTwoTime(start, end, ChronoUnit.MILLIS));
        log.info("================================== 时间大小 ===================================");
        //t1 < t2 = true
        log.info("2019-10-13 11:11:00 < 2020-11-13 13:13:00 = " + isBefore(start, end));
        //t1 > t2 = true
        log.info("2019-10-13 11:11:00 > 2020-11-13 13:13:00 = " + isAfter(start, end));
    }

    private static void test2() {
        log.info("================================== 周几 ===================================");
        LocalDateTime of1 = LocalDateTime.of(2020, 4, 20, 0, 0);
        LocalDateTime of2 = LocalDateTime.of(2020, 4, 21, 0, 0);
        LocalDateTime of3 = LocalDateTime.of(2020, 4, 22, 0, 0);
        LocalDateTime of4 = LocalDateTime.of(2020, 4, 23, 0, 0);
        LocalDateTime of5 = LocalDateTime.of(2020, 4, 24, 0, 0);
        LocalDateTime of6 = LocalDateTime.of(2020, 4, 25, 0, 0);
        LocalDateTime of7 = LocalDateTime.of(2020, 4, 26, 0, 0);
        log.info(parse(of1, "yyyy-MM-dd") + " 是周 " + week(of1));
        log.info(parse(of2, "yyyy-MM-dd") + " 是周 " + week(of2));
        log.info(parse(of3, "yyyy-MM-dd") + " 是周 " + week(of3));
        log.info(parse(of4, "yyyy-MM-dd") + " 是周 " + week(of4));
        log.info(parse(of5, "yyyy-MM-dd") + " 是周 " + week(of5));
        log.info(parse(of6, "yyyy-MM-dd") + " 是周 " + week(of6));
        log.info(parse(of7, "yyyy-MM-dd") + " 是周 " + week(of7));
        log.info("=========================== 周开头和结束 ===============================");
        log.info(" 上周的周一是 " + weekFirstDay(LocalDateTime.now(), -1));
        log.info(" 上周的周末是 " + weekLastDay(LocalDateTime.now(), -1));
        log.info(" 本周的周一是 " + weekFirstDay(LocalDateTime.now(), 0));
        log.info(" 本周的周末是 " + weekLastDay(LocalDateTime.now(), 0));
        log.info(" 下周的周一是 " + weekFirstDay(LocalDateTime.now(), 1));
        log.info(" 下周的周末是 " + weekLastDay(LocalDateTime.now(), 1));
        log.info("=========================== 月开头和结束 ===============================");
        log.info(" 上月的月初是 " + weekFirstDay(LocalDateTime.now(), -1));
        log.info(" 上月的月位是 " + weekLastDay(LocalDateTime.now(), -1));
        log.info(" 本月的月初是 " + weekFirstDay(LocalDateTime.now(), 0));
        log.info(" 本月的月位是 " + weekLastDay(LocalDateTime.now(), 0));
        log.info(" 下月的月初是 " + weekFirstDay(LocalDateTime.now(), 1));
        log.info(" 下月的月位是 " + weekLastDay(LocalDateTime.now(), 1));
        log.info("==================== 当前月1好到下N月底的每天数据 =========================");
        log.info(" 前N月|后N月 -- 前N月|后N月所有时间 " + XjLocalDateTimeUtil.getBetweenDaysUpListByMonth(LocalDateTime.now(), 0, 2).toString());
        log.info(" 前N月|后N月 -- 前N月|后N月所有时间 " + XjLocalDateTimeUtil.getBetweenDaysUpListByMonth(LocalDateTime.now(), 2, 2).toString());

    }


    private static void test3() {
        log.info("==================获取指定开始时间和结束时间内的所有时间 ====================");
        LocalDateTime startTime = LocalDateTime.of(2020, 4, 20, 0, 0);
        LocalDateTime endTime = LocalDateTime.of(2020, 4, 25, 0, 0);
        log.info("1-包含开始和结束时间" + getBetweenDaysList(startTime, endTime, 1));
        log.info("2-包含结束-不包含开始时间" + getBetweenDaysList(startTime, endTime, 2));
        log.info("3-包含开始-不包含结束时间" + getBetweenDaysList(startTime, endTime, 3));
        log.info("4-不包含开始和结束时间" + getBetweenDaysList(startTime, endTime, 4));
        log.info("================== LocalDateTime与String日期互相转换 ====================");
        log.info(parse("2020-01-20 17:07:05").toString());
        log.info(parse(LocalDateTime.now()));
        log.info("================== 时间特殊格式方法转换 ==================");
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY));
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM));
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM_DD));
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM_DD_HH));
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM_DD_HH_MM));
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM_DD_HH_MM_SS));
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM_DD_HH_MM_SS_SSS));
        log.info(parse(new Date(), DateFormat.YYYY_MM_DD));
        log.info(parse("2020", DateFormat.YYYY).toString());
        log.info(parse("2020-06", DateFormat.YYYY_MM).toString());
        log.info(parse("2020-06-06", DateFormat.YYYY_MM_DD).toString());
        log.info(parse("2020-06-06 00", DateFormat.YYYY_MM_DD_HH).toString());
        log.info(parse("2020-06-06 00:00", DateFormat.YYYY_MM_DD_HH_MM).toString());
        log.info(parse(LocalDateTime.now(), DateFormat.YYYY_MM));
        log.info("==================获取整时时间,舍弃分秒为0 ==================");
        log.info(parse(getTheHour(LocalDateTime.now())));
        log.info("==================获取整分时间,舍弃秒为0");
        log.info(parse(getTheMinute(LocalDateTime.now())));
        log.info(parse(getTheMinute(LocalDateTime.of(2020, 1, 1, 12, 50))));
        log.info("==================获取指定时间内的每月");
        log.info(getBetweenMonthsList(subtract(LocalDateTime.now(), 1, ChronoUnit.YEARS), LocalDateTime.now()).toString());
        log.info("==================获取指定天的24小时");
        List<String> day24Hour = getDay24Hour(LocalDateTime.now());
        log.info(day24Hour.toString());
    }


    private static void test4() {
        log.info("转为时间戳(秒级): " + parseTimestamp(parse("2021-01-01 00:00:00")) + "");
        log.info("转为时间戳(毫秒级): " + parseTimestampMilli(parse("2021-01-01 00:00:00")) + "");

        log.info("转回时间戳(秒级): " + parseTimestamp(1609430400L));
        log.info("转回时间戳(毫秒级): " + parseTimestampMilli(1609430400000L));
    }
}
